1 module hip.data.csv;
2 
3 struct CSV
4 {
5     string[][] data;
6     string path;
7 }
8 
9 
10 CSV parseCSV(string data, const char fieldDelimiter = ',', const char textDelimiter = '"', string path = "")
11 {
12     CSV ret;
13     ret.path = path;
14     size_t left = 0;
15     bool hadDelimiter = false;
16     bool lookingForEndOfTextDelimiter = false;
17     string[] currentLine;
18     foreach(i, ch; data)
19     {
20         switch(ch)
21         {
22             case fieldDelimiter:
23                 if(!lookingForEndOfTextDelimiter)
24                 {
25                     if(hadDelimiter)
26                     {
27                         hadDelimiter = false;
28                         currentLine~= data[left+1..i-1];
29                     }
30                     else
31                     {
32                         currentLine~= data[left..i];
33                     }
34                     left = i+1;
35                 }
36                 break;
37             case '\n':
38                 if(!lookingForEndOfTextDelimiter)
39                 {
40                     if(hadDelimiter)
41                     {
42                         hadDelimiter = false;
43                         currentLine~= data[left+1..i-1];
44                     }
45                     else
46                     {
47                         currentLine~= data[left..i];
48                     }
49                     ret.data~= currentLine;
50                     currentLine.length = 0;
51                     left = i+1;
52                 }
53                 break;
54             case textDelimiter:
55                 hadDelimiter = true;                
56                 //If the first character at left is the text delimiter, the entire slot is filled with text delimiter
57                 lookingForEndOfTextDelimiter = !lookingForEndOfTextDelimiter;
58                 break;
59             default:break;
60         }
61     }
62     return ret;
63 }